package com.ucar.achievement.util;

import com.ucar.achievement.model.AchievePostVO;
import com.ucar.driverWallet.coaccount.callback.AchievementComputeCallback;
import com.ucar.driverWallet.coaccount.model.CodriverAchievementVO;
import com.ucar.util.NumberUtil;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description:业绩计算工具类 <br/>
 * @version V1.0  by 石冬冬-Heil Hitler on  2017/5/27 16:43
 */
public class AchievementUtils {
    private AchievementUtils(){}
    /**
     * Description: 根据相关司机，计算出每个司机的待核实业绩提成<br>
     * @version V1.0 2017/5/27 16:28  by 石冬冬-Heil Hilter（dd.shi02@zuche.com)
     * 需求：待核实业绩提成 = Σ【（业绩提成-提成入账金额）+（垫付费用-垫付入账金额）-（扣税金额-扣税入账金额）】
     * 转换思路：待核实业绩提成 = Σ【（业绩提成+垫付费用-扣税金额）-（提成入账金额+垫付入账金额-扣税入账金额）】
     * @param computeCallback
     * @return
     */
    public static Map<Long,BigDecimal> computeUnverifyCommission(AchievementComputeCallback computeCallback){
        Map<Long, BigDecimal> resultMap = new HashMap<Long, BigDecimal>();
        computeCallback.check();
        List<Long> driverList = computeCallback.getDriverList();
        List<CodriverAchievementVO> achivementList = computeCallback.getAchivementList();//订单业绩记录
        List<AchievePostVO> postList = computeCallback.getPostList();//业绩入账明细记录
        //存储每个司机的订单业绩计算出的金额
        Map<Long,BigDecimal> achivementGroupMap = eachPut(achivementList, new GetComputeMoney<CodriverAchievementVO>() {
            @Override
            public Long getKey(CodriverAchievementVO vo) {
                return vo.getDriverId();
            }

            @Override
            public BigDecimal getMoney(CodriverAchievementVO codriverAchievementVO) {
                return codriverAchievementVO.getCommission().add(codriverAchievementVO.getDisbursement()).subtract(codriverAchievementVO.getDeduction());
            }
        });
        //存储每个司机的订单业绩入账计算出的金额
        Map<Long,BigDecimal> postGroupMap = eachPut(postList, new GetComputeMoney<AchievePostVO>() {
            @Override
            public Long getKey(AchievePostVO vo) {
                return vo.getDriverId();
            }

            @Override
            public BigDecimal getMoney(AchievePostVO achievePostVO) {
                return achievePostVO.getCommissionPost().add(achievePostVO.getDisbursementPost()).subtract(achievePostVO.getDeductionPost());
            }
        });
        final BigDecimal ZERO = BigDecimal.ZERO;
        for(Long driverId : driverList){
            BigDecimal money = NumberUtil.isNull(achivementGroupMap.get(driverId),ZERO).subtract(NumberUtil.isNull(postGroupMap.get(driverId),ZERO));
            resultMap.put(driverId,money);
        }
        return resultMap;
    }

    /**
     * 以司机纬度，循环不同集合，对每个集合元素对象相关金额进行计算并累加
     * @param list 集合
     * @param computer
     * @param <E>
     * @return
     */
    private static <E> Map<Long,BigDecimal> eachPut(List<E> list,GetComputeMoney computer){
        Map<Long,BigDecimal> resultMap = new HashMap<Long, BigDecimal>();
        if(null != list && !list.isEmpty()){
            for (E e : list){
                Long key = computer.getKey(e);
                if(resultMap.containsKey(key)){
                    resultMap.put(key,resultMap.get(key).add(computer.getMoney(e)));
                }else{
                    resultMap.put(key,computer.getMoney(e));
                }
            }
        }
        return resultMap;
    }

    private interface GetComputeMoney<E>{
        /**
         * 获取循环对象的key
         * @param e
         * @return
         */
        Long getKey(E e);
        /**
         * 获取循环对象 的当前计算金额
         * @param e
         * @return
         */
        BigDecimal getMoney(E e);
    }

    /**
     * 该方法用于订单业绩详情页面，相关金额需要精确小数点后两位
     * @param value
     * @return
     */
    public static BigDecimal setScale(BigDecimal value){
        if(null != value){
            return value.setScale(2,BigDecimal.ROUND_HALF_UP);
        }
        return value;
    }

    public static void main(String[] args) {
        System.out.println(setScale(new BigDecimal(0.00000)));
    }
}
